package com.bolt.report.business.modules.report.service;

import com.bolt.common.reflect.ObjectUtil;
import com.bolt.convention.exception.ServiceException;
import com.bolt.core.view.components.BindDataModel;
import com.bolt.report.business.modules.dataset.service.ReportDataSetService;
import com.bolt.report.business.modules.datasource.service.ReportDataSourceService;
import com.bolt.report.definition.DataSetDefinition;
import com.bolt.report.definition.DataSetType;
import com.bolt.report.definition.JdbcDataSourceDefinition;
import com.bolt.report.engine.BRDataSource;
import com.bolt.report.engine.ObjectFactory;
import com.bolt.report.engine.pool.JdbcConnectionPool;
import com.bolt.report.engine.query.QueryExecute;
import com.bolt.report.engine.query.QueryExecuteFactory;
import lombok.extern.slf4j.Slf4j;
import net.sf.jasperreports.engine.JRParameter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.util.Map;

@Service
@Slf4j
public class FormItemBindDataService {

    @Autowired
    private ReportDataSourceService dataSourceService;

    @Autowired
    private ReportDataSetService dataSetService;

    @Autowired
    private JdbcConnectionPool jdbcConnectionPool;

    private DataSetDefinition createDataSetDefinition(BindDataModel bindData) {
        if (bindData.getBindType() == 2) {
            JdbcDataSourceDefinition dataSourceDefinition = dataSourceService.findDataSourceDefinition(bindData.getDbSourceId());
            DataSetDefinition dataSetDefinition = new DataSetDefinition();
            dataSetDefinition.setQuerySql(bindData.toSql());
            dataSetDefinition.setJdbcConnectionDef(dataSourceDefinition);
            dataSetDefinition.setType(DataSetType.SQL);
            return dataSetDefinition;
        } else {
            DataSetDefinition dataSetDefinition = dataSetService.findDataSourceDefinition(bindData.getDataSetId());
            return dataSetDefinition;
        }

    }

    public QueryExecute createQueryExecute(BindDataModel bindData, Map param) {
        try {
            DataSetDefinition dataSetDefinition = createDataSetDefinition(bindData);
            if(ObjectUtil.isNotNull(dataSetDefinition.getJdbcConnectionDef())){
                Connection connection = jdbcConnectionPool.getPooledConnection(dataSetDefinition.getJdbcConnectionDef());
                param.put(JRParameter.REPORT_CONNECTION, connection);
            }
            QueryExecuteFactory queryExecuteFactory = ObjectFactory.getQueryExecuterFactory();
            QueryExecute queryExecute = queryExecuteFactory.createQueryExecuter(dataSetDefinition, param);
            return queryExecute;
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            throw new ServiceException(ex);
        }
    }



    public BRDataSource executeDataSet(BindDataModel bindData, Map param) {
        QueryExecute queryExecute = createQueryExecute(bindData, param);
        BRDataSource dataSource = queryExecute.createBRDataSource();
        return dataSource;
    }


}